const path = require('path');
const helper = require('./helper');
const cfg_app = require('./config').app;
const artTemplate = require('art-template');

const errTemp = `
  <style>
    #list { line-height: 36px; padding: 0; }
    #list li { padding-left: 8px; }
    #list li:nth-of-type(odd){ background:#FFCC99;}
    #list li:nth-of-type(even){ background:#FFFFCC;}
  </style>
  <body style="margin:30px; padding: 50px;border: 1px solid #c2c2c2;">
  <h3 style="color: red;border-bottom:1px solid red;">错误信息：{{message}}</h3>
  <ul id="list">
  {{each stack}}
    <li>{{$value}}</li>
  {{/each}}
  </ul>
  <p style="color: #989898; text-align: center; font-size: 14px; margin-top: 30px;">zsjs - 一个简单的NodeJS后端MVC框架</p>
  </body>
`;

const reg = /^[a-zA-Z]+$/;

/**
 * 执行函数
 * @param {Object} ctx 
 * @param {Function} next 
 * @param {String} type 表示文件名，默认controller，可选view
 */
async function runAction(ctx, next, type) {

  if (!reg.test(ctx.application) || cfg_app.deny_apps.includes(ctx.application)) {
    throw new Error(`${ctx.application}应用命名不合法！`);
  }

  if (!reg.test(ctx.controller)) {
    throw new Error(`${ctx.application}应用，${ctx.controller}控制器命名不合法`);
  }

  if (!reg.test(ctx.action)) {
    throw new Error(`${ctx.application}应用，${ctx.controller}控制器下，${ctx.action}方法命名不合法`);
  }

  // 判断应用是否属于禁止的应用名，如common是禁止url默认访问的
  if (!ctx.$zs[ctx.application]) {
    if (cfg_app.app_debug) {
      throw new Error(`应用${ctx.application}不存在！`);
    }
    return;
  }

  //模版文件内容直接输出
  if (type == cfg_app.view_folder) {
    const content = await helper.readFile(path.join(ctx.$zs[ctx.application][type].$path, ctx.controller + cfg_app.view_depr + ctx.action + cfg_app.view_ext));
    if (!content && cfg_app.app_debug) {
      throw new Error(`模板文件:${ctx.application}/${type}/${ctx.controller + cfg_app.view_depr + ctx.action + cfg_app.view_ext}不存在！`)
    }
    ctx.body = content;
    return;
  }

  if (!ctx.$zs[ctx.application][type]) {
    if (cfg_app.app_debug) {
      throw new Error(`目录:${ctx.application}/${type}不存在！`);
    }
    return;
  }

  if (!ctx.$zs[ctx.application][type][ctx.controller]) {
    if (cfg_app.app_debug) {
      throw new Error(`文件或模板目录:${ctx.application}/${type}/${ctx.controller}不存在！`);
    }
    return;
  }

  if (typeof ctx.$zs[ctx.application][type][ctx.controller][ctx.action] != 'function') {
    if (cfg_app.app_debug) {
      throw new Error(`方法:${ctx.application}/${type}/${ctx.controller}/${ctx.action}不存在！`);
    }
    return;
  }

  //执行控制器方法
  await ctx.$zs[ctx.application][type][ctx.controller][ctx.action]();
}

async function run(ctx, next, type = cfg_app.controller_folder) {
  try {
    await runAction(ctx, next, type);
  } catch (error) {
    ctx.status = 503;
    if (cfg_app.app_debug) {  // 开启调试之后
      ctx.body = artTemplate.render(errTemp, {
        message: error.message,
        stack: error.stack.split('\n').slice(1),
      });
    } else { // 没有开启调试
      ctx.body = '<h1>服务端错误!</h1>';
    }
  }
}

module.exports = run;